<template>
  <el-select v-model="modelValue"
             clearable
             filterable
             :remote-method="handleSearch"
             reserve-keyword
             :placeholder="props.placeholder"
             :loading="_loading"
             @change="change"
  >
    <template v-for="item in options" :key="props.optionKey">
      <slot :option-data="item"></slot>
    </template>

    <div class="next-page" @click="getNextPage">
      <template v-if="!_finished">点击加载更多</template>
      <template v-else-if="_loading">加载中</template>
      <template v-else>已全部加载</template>
    </div>
  </el-select>
</template>

<script lang="ts" setup>
import {debounce} from "@/utils";
import {request,post} from "@/utils/request";
import ApiResult from "@/api/base/ApiResult";

const props = withDefaults(defineProps<{
  modelValue: any, // 绑定值
  url: string, // 远程连接
  searchKey: string, // 输入的搜索value 会被赋值到这个key上 传递给接口
  optionKey: string | number, // option 渲染优化用的唯一key
  params?: object, // 传递给接口的其他参数
  placeholder?: string
}>(), {
  modelValue: '',
  url: '',
  searchKey: 'name',
  params: () => ({}),
  optionKey: 'id',
  placeholder: '输入搜索'
})

const emits = defineEmits([
    "update:loading",
    "update:finished",
    "update:model-value",
    "change"
])

const modelValue = computed({
  get: () => props.modelValue,
  set: (newValue) => emits('update:model-value', newValue)
})

const change = (val: any) => {
  emits('change', val, options.value)
}

const _loading = ref(false)
const _finished = ref(false)

const pager = reactive({
  showCount: 10,
  currentPage: 1,
})
const options = ref([])


const getRemoteData = async (query?: string) => {
  _loading.value = true
  const rs:ApiResult<any> = await request(props.url, {
    ...pager,
    [props.searchKey]: query ?? '',
    ...props.params
  })
  _loading.value = false

  if (rs.code === 200) {
    options.value = options.value.concat(rs.payload)
    _finished.value = (rs.page?.currentPage ?? 1) >= (rs.page?.totalPage ?? 0)
  }
}

const handleSearch = debounce((query: string) => {
  // console.log(query)
  pager.currentPage = 1
  options.value = []
  getRemoteData(query)
}, 700, false)

const getNextPage = () => {
  if (_loading.value) {
    return
  }

  if (_finished.value) {
    return
  }

  ++pager.currentPage
  getRemoteData()
}

onMounted(() => {
  getRemoteData()
})
</script>

<style scoped lang="scss">

.next-page {
  padding: 10px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #999;
  cursor: pointer;
}
</style>
